package credential

import (
	"fmt"
	"github.com/emicklei/go-restful"
	"kubeInstall/pkg/logger"
	"kubeInstall/server/handlers"
	cluster2 "kubeInstall/server/models/cluster"
	"kubeInstall/server/services/credential"
	"net/http"
	"strconv"
)

type credentialHandler struct {
	handlers.BaseHandler
}

func NewCredentialHandler() handlers.IBaseHandler {
	return new(credentialHandler)
}

func (c *credentialHandler) AddToRoute(ws *restful.WebService) {

	ws.Route(ws.GET("/credential/{credential_id}").To(c.getCredential))
	// add credential
	ws.Route(ws.POST("/credential").To(c.addCredential))
	// delete credential
	ws.Route(ws.DELETE("/credential/{credential_id}").To(c.deleteCredential))
	// list credential
	ws.Route(ws.GET("/credential").To(c.listCredential))
	// update credential
	ws.Route(ws.PUT("/credential/{credential_id}").To(c.updateCredential))
	logger.Info("add credential module successfully")
}
func (c *credentialHandler) addCredential(r *restful.Request, resp *restful.Response) {

	var req cluster2.Credential
	if err := r.ReadEntity(&req); err != nil {
		c.RenderError(resp, fmt.Sprintf("read credential from http body failed,error is :%v", err), http.StatusInternalServerError)
		return
	}
	// 判断类型是否为密码或者是ssh数据。
	if req.Type != "password" && req.Type != "ssh" {
		c.RenderError(resp, fmt.Sprintf("credential type %s must be password or ssh", req.Type), http.StatusBadRequest)
		return
	}

	result, err := credential.AddCredential(&req)

	if err != nil {
		c.RenderError(resp, fmt.Sprintf("create credential failed! error is :%v", err), http.StatusBadRequest)
		return
	}
	c.RenderResp(resp, result, http.StatusOK)

}

func (c *credentialHandler) getCredential(r *restful.Request, resp *restful.Response) {

	credentialId := r.PathParameter("credential_id")
	if credentialId == "" {
		c.RenderError(resp, fmt.Sprintf("get Credential id from http query failed!"), http.StatusBadRequest)
		return
	}
	data, err := credential.GetCredential(credentialId)

	if err != nil {
		c.RenderError(resp, fmt.Sprintf("get credential failed! error is: %v", err), http.StatusNotFound)
		return
	}

	c.RenderResp(resp, data, http.StatusOK)

}

func (c *credentialHandler) listCredential(r *restful.Request, resp *restful.Response) {

	offset, _ := strconv.Atoi(r.QueryParameter("offset"))
	limit, _ := strconv.Atoi(r.QueryParameter("limit"))

	result, err := credential.ListCredentials(limit, offset)
	if err != nil {
		c.RenderError(resp, fmt.Sprintf("list credential failed! error is %v", err), http.StatusInternalServerError)
		return
	}

	c.RenderResp(resp, result, http.StatusOK)

}

func (c *credentialHandler) deleteCredential(r *restful.Request, resp *restful.Response) {

	credentialId := r.PathParameter("credential_id")
	if credentialId == "" {
		c.RenderError(resp, fmt.Sprintf("get Credential id from http query failed!"), http.StatusBadRequest)
		return
	}

	if err := credential.DeleteCredential(credentialId); err != nil {
		c.RenderError(resp, fmt.Sprintf("delete credential failed! error is  %v", err), http.StatusNotFound)
		return
	}

	result := handlers.SuccessResp{
		StatusCode: http.StatusOK,
		Message:    fmt.Sprintf("Delete %s Success", credentialId),
	}

	c.RenderResp(resp, result, http.StatusOK)

}

func (c *credentialHandler) updateCredential(r *restful.Request, resp *restful.Response) {
	var cred cluster2.Credential
	credentialId := r.PathParameter("credential_id")
	if credentialId == "" {
		c.RenderError(resp, fmt.Sprintf("get Credential id from http query failed!"), http.StatusBadRequest)
		return
	}

	if err := r.ReadEntity(&cred); err != nil {
		c.RenderError(resp, fmt.Sprintf("read credential from http body failed,error is :%v", err), http.StatusBadRequest)
		return
	}

	// todo 更新参数校验:
	if cred.Type != "password" && cred.Type != "ssh" {
		c.RenderError(resp, fmt.Sprintf("credential type %s must be password or ssh", cred.Type), http.StatusBadRequest)
		return
	}

	if err := credential.UpdateCredential(credentialId, &cred); err != nil {
		c.RenderError(resp, fmt.Sprintf("update credential failed! error is  %v", err), http.StatusBadRequest)
		return
	}

	data, err := credential.GetCredential(credentialId)

	if err != nil {
		c.RenderError(resp, fmt.Sprintf("get credential failed! error is: %v", err), http.StatusBadRequest)
		return
	}
	c.RenderResp(resp, data, http.StatusOK)

}
